package io.github.chutian0610.sqlparser.token

import arrow.core.None
import arrow.core.Option
import io.github.chutian0610.sqlparser.Location

/** TokenizerContext
 * Context for Tokenizer.
 */
class TokenizerContext private constructor(
    private val codePointCharStream: CodePointCharStream,
    private val tokens: MutableList<TokenWithLocation>
) {
    fun peek(): CodePoint? = codePointCharStream.peek()
    fun peek(index: Int): CodePoint? = codePointCharStream.peek(index)
    fun next(): CodePoint? = codePointCharStream.next()
    fun slice(): TokenizerContext {
        val sliceChar = codePointCharStream.slice()
        val sliceTokens: MutableList<TokenWithLocation> = mutableListOf()
        return TokenizerContext(sliceChar, sliceTokens)
    }

    fun location(): Location = codePointCharStream.location()
    fun tokens(): MutableList<TokenWithLocation> = tokens
    fun lastToken(): Option<Token> {
        if (tokens.isEmpty()) {
            return None
        } else {
            return Option.fromNullable(tokens.last().token)
        }
    }

    companion object {
        fun fromString(str: String): TokenizerContext {
            return TokenizerContext(CodePointCharStream.fromString(str), mutableListOf())
        }
    }
}